<template>
  <div id="app">
    <router-view @login='loginIn' @loginOut='accountOut'></router-view>
  </div>
</template>

<script>
import Vue from 'vue'
import role from '@/api/signin'
import fullPah from '@/router/fullRoutes'
import { fetch } from '@/api'
// 请求拦截句柄
let myInterceptor
export default {
  name: 'App',
  data () {
    return {
      menuData: null,
      userData: null
    }
  },
  methods: {
    loginIn () {
      let vm = this
      vm.checkSignin(() => {
        vm.$router.replace({
          path: '/'
        })
      })
    },
    // 退出
    accountOut () {
      // 清除cookie
      this.delCookie('token')
      // this.setSession('token', '')
      // 清除请求权限控制
      fetch.interceptors.request.eject(myInterceptor)
      // 清除菜单权限
      this.$root.hashMenus = {}
      // 清除请求头token
      fetch.defaults.headers.common['Authorization'] = ''
      console.log(this.$root.hashMenus)
      // 回到登录页
      if (!this.getCookie('token')) {
        this.$router.replace({path: '/login'})
      }
    },
    getPermission ({resources}) {
      let resourcesPermission = {}
      if (Array.isArray(resources)) {
        resources.forEach((item, index) => {
          let key = item.method.toLowerCase() + ',' + item.url
          resourcesPermission[key] = true
        })
      }
      return resourcesPermission
    },
    // 设置请求config
    setFetchConfig (resourcesPermission) {
      console.log(resourcesPermission)
      let vm = this
      myInterceptor = fetch.interceptors.request.use(config => {
        // 得到请求的路径
        let perName = config.url.replace(config.baseURL, '').replace('/GET', '').replace('/POST', '').split('?')[0]
        // 校验权限
        if (!resourcesPermission[`${config.method},${perName}`]) {
          vm.$Message.error(`没有权限哦`)
          return
        }
        return config
      })
    },
    getRoutes (menus) {
      if (!menus) {
        return console.warn(menus)
      }
      let vm = this
      let allowRouter = []
      // 将一维菜单数据转换成多维数组结构
      let arryMenus = vm.buildMenu(menus)
      // 将多维数组格式转换为对象格式 对象的键名就是路由的path 并且对子路由的path拼接
      let hashMenus = {}
      let setMenu2Hash = (arry, base) => {
        arry.map(key => {
          if (key.route) {
            let hashKey = ((base ? base + '/' : '') + key.route).replace(/^\//, '')
            hashMenus[`/${hashKey}`] = true
            if (Array.isArray(key.children)) {
              setMenu2Hash(key.children, key.route)
            }
          }
        })
      }
      setMenu2Hash(arryMenus)
      // 全局挂载hashMenus 实现路由守卫
      this.$root.hashMenus = hashMenus
      // 筛选本地路由的方法 比对fullroutes和后端返回的路由
      let findLocalRoute = (array, base) => {
        let replyResult = []
        array.forEach(route => {
          let pathKey = ((base ? base + '/' : '')) + route.path
          if (hashMenus[pathKey]) {
            if (Array.isArray(route.children)) {
              findLocalRoute(route.children, route.path)
            }
            replyResult.push(route)
          }
        })
        if (base) {
          return replyResult
        } else {
          allowRouter = allowRouter.concat(replyResult)
        }
      }
      let originPath = vm.cloneObj(fullPah[0].children)
      findLocalRoute(originPath)
      return allowRouter
    },
    async checkSignin (callback) {
      let vm = this
      // let localUser = vm.setSession('token')
      let localUser = vm.getCookie('token')
      console.log(localUser)
      if (!localUser) {
        return vm.$router.push({
          path: '/login'
        })
      }
      // 给请求头添加token
      fetch.defaults.headers.common['Authorization'] = localUser
      let result = await role.request.r({user: `${localUser}`})
      // 获取资源权限对象
      let resourcesPermission = vm.getPermission(result.data)
      // 设置请求拦截判断资源权限
      vm.setFetchConfig(resourcesPermission)
      // 获取实际路由
      let allowedRouter = vm.getRoutes(result.data.menus)
      // 动态注入路由
      await vm.extendRoutes(allowedRouter)
      // 保存数据
      vm.menuData = allowedRouter
      vm.userData = result.data
      console.log(`菜单数据${JSON.stringify(vm.menuData)} 用户数据${JSON.stringify(vm.userData)}`)
      // 设置权限校验方法用于控制按钮显示隐藏
      Vue.prototype.$_has = (rArray) => {
        let resources = []
        let permission = true
        if (Array.isArray(rArray)) {
          rArray.forEach(e => {
            resources = resources.concat(e.p)
          })
        } else {
          resources = resources.concat(rArray.p)
        }
        // 校验权限
        console.log(resources, resourcesPermission)
        resources.forEach(item => {
          if (!resourcesPermission[item]) {
            permission = false
          }
        })
        return permission
      }
      // 执行回调
      typeof callback === `function` && callback()
    },
    extendRoutes (allowedRouter) {
      let vm = this
      let actualRouter = vm.cloneObj(allowedRouter)
      actualRouter.map(e => {
        // 复制子菜单信息到meta用于实现导航相关效果，非必需
        if (e.children) {
          if (!e.meta) e.meta = {}
          e.meta.children = e.children
        }
        // 为动态路由添加独享守卫
        e.beforeEnter = (to, from, next) => {
          if (vm.$root.hashMenus[to.path]) {
            next()
          } else {
            next('/401')
          }
        }
        return e.beforeEnter
      })
      let originPath = vm.cloneObj(fullPah)
      originPath[0].children = actualRouter
      vm.$router.addRoutes(originPath.concat([{
        path: '*',
        redirect: '/404'
      }]))
    }
  },
  created () {
    this.checkSignin()
  }
}
</script>

<style>

</style>
